package com.lhcai.nk.medium;

/**
 * @author lhcstart
 * @create 2023-02-21 10:13
 */

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;


/**
 * 描述
 * 给出4个1-10的数字，通过加减乘除运算，得到数字为24就算胜利,除法指实数除法运算,运算符仅允许出现在两个数字之间,本题对数字选取顺序无要求，但每个数字仅允许使用一次，且需考虑括号运算
 * 此题允许数字重复，如3 3 4 4为合法输入，此输入一共有两个3，但是每个数字只允许使用一次，则运算过程中两个3都被选取并进行对应的计算操作。
 * 输入描述：
 * 读入4个[1,10]的整数，数字允许重复，测试用例保证无异常数字。
 * 输出描述：
 * 对于每组案例，输出一行表示能否得到24点，能输出true，不能输出false
 */
public class HJ67 {
    public static int[] arr;//存放输入数据
    public static int[] temp;//用于判断对应序号的整数有没有被使用。

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            arr = new int[4];
            temp = new int[4];
            for (int i = 0; i < 4; i++) {
                arr[i] = sc.nextInt();
            }
            System.out.println(solve(0, 0));
        }
    }

    //cnt代表已使用的数据数，sum代表临时计算的结果
    public static boolean solve(int cnt, double sum) {

        if (cnt == 4 && sum == 24) {//如果用了4个了，且结果已经是24了，那就说明24运算成功。
            return true;
        }

        if (cnt == 0) {//对于还没开始运算的情况，接收的第一个数值直接作为sum
            for (int i = 0; i < 4; i++) {
                //默认为可以使用
                temp[i] = 1;
                if (solve(1, arr[i])) {
                    return true;
                }
                //能得到结果在上一步就return,得不到，将使用过的书取出来
                temp[i] = 0;//恢复现场
            }
            return false;
        }

        if (cnt == 2) {
            //对于已经在两个数值参加运算的情况，要考虑两种可能
            //1.另两个数字参加运算后再和当前结果运算。
            int a = 0, b = 0;
            for (int i = 0; i < 4; i++) {
                //没有使用过
                if (temp[i] == 0) {
                    //a没有使用过，数据的取值范围[1,10]
                    if (a == 0) {
                        a = arr[i];
                    } else {
                        b = arr[i];
                    }
                }
            }

            for (Double n : res(a, b)) {//对所有可能的ab计算结果遍历
                for (Double m : res(sum, n)) {//将ab的计算结果与另外两个数之间的计算结果  再进行计算遍历
                    if (m == 24) {
                        return true;
                    }
                }
            }
            //2.当前结果与第三个数值参加运算。
            for (int i = 0; i < 4; i++) {
                if (temp[i] == 0) {
                    temp[i] = 1;
                    //加减乘
                    if (solve(3, sum + arr[i]) || solve(3, sum * arr[i])
                            || solve(3, sum - arr[i]) || solve(3, arr[i] - sum)) {
                        return true;
                    }
                    //除，需要判断分母不为零
                    if ((sum != 0 && solve(3, arr[i] / sum)) ||
                            (arr[i] != 0 && solve(3, sum / arr[i]))) {
                        return true;
                    }
                    temp[i] = 0;
                }
            }
            return false;
        }

        if (cnt == 1 || cnt == 3) {
            for (int i = 0; i < 4; i++) {
                if (temp[i] == 0) {
                    temp[i] = 1;
                    //加减乘
                    if (solve(cnt + 1, sum + arr[i]) || solve(cnt + 1, sum * arr[i])
                            || solve(cnt + 1, sum - arr[i]) || solve(cnt + 1, arr[i] - sum)) {
                        return true;
                    }
                    //除，需要判断分母不为零
                    if ((sum != 0 && solve(cnt + 1, arr[i] / sum)) || (arr[i] != 0 && solve(cnt + 1, sum / arr[i]))) {
                        return true;
                    }
                    temp[i] = 0;
                }
            }
        }//不是1~4的返回false
        return false;
    }


    //存放所有可能的加减乘除
    public static List<Double> res(double a, double b) {
        List<Double> list = new ArrayList<>();
        list.add(a + b);
        list.add(a * b);
        list.add(a - b);
        list.add(b - a);
        if (a != 0) {
            list.add(b / a);
        }
        if (b != 0) {
            list.add(a / b);
        }
        return list;

    }
}
